
/**
 * @author EklipZ
 *
 */
public class CheckingAccount extends AbstractAccount
{
	public static final boolean DEFAULT_ACCOUNT_DEBIT_ALLOWED = false;
	public static final double DEFAULT_ACCOUNT_DEBIT_LIMIT = 0.0;
	
	/**
	 * whether or not the account is allowed to go negative.
	 */
	private boolean fDebitAllowed;
	/**
	 * The amount negative to which the account is allowed to go.
	 */
	private double fDebitAmount;
	
	/** 
	 * per period there is a cost associated with this account that equals 1 pound
	 */
	private static double costs = 1;
	/**
	 * the interest compounded on accounts that are negative at the end of the period.
	 */
	private static double debitRate = 4.7;

	
	/**
	 * Constructs a new checking account, storing the passed owner. Debit is based on default values at top of file.
	 * 
	 * @param the_owner the accounts owner, Person object.
	 */
	public CheckingAccount(final Person the_owner)
	{
		super(the_owner);
		
		fDebitAllowed = DEFAULT_ACCOUNT_DEBIT_ALLOWED;
		fDebitAmount = DEFAULT_ACCOUNT_DEBIT_LIMIT;
		
	}
	
	/**
	 * Constructs a new checking account, storing the passed owner. Debit is based on the passed in value.
	 * 
	 * @param the_owner the accounts owner, Person object.
	 * @param debit the amount the account is allowed to go negative.
	 * @param the_balance	the starting balance for the account.
	 */
	public CheckingAccount(Person the_owner, float debit, 
			               double the_balance)
	{
		super(the_owner, the_balance);
		fDebitAllowed = true;
		fDebitAmount = debit;
	}
	
	
	/**
	 * Constructs a new checking account, storing the passed owner. Debit is based on default values at top of file.
	 * 
	 * @param the_owner the accounts owner, Person object.
	 */
	public CheckingAccount(int accountnumber)
	{
		super(accountnumber);
		fDebitAllowed = DEFAULT_ACCOUNT_DEBIT_ALLOWED;
		fDebitAmount = DEFAULT_ACCOUNT_DEBIT_LIMIT;
	}
	
	
	/**
	 * Determines the quarterly costs.
	 */
	public void determineCosts()
	{
		setBalance(getBalance() - costs);
		if(getBalance() < 0)
		{
			setBalance(getBalance() - (getBalance() * debitRate / 100));
		}
	}
	
	
	
	/**
	 * Prints the state of the checking account.
	 */
	public void print()
	{
		System.out.println("**************************************");
		System.out.println("Checking account:     " + getAccountNumber());
		System.out.println("Account holder name: " + getOwner().getName());
		System.out.println("Address:             " + getOwner().getStreet());
		System.out.print("                     " + getOwner().getZipCode());
		System.out.println(" " + getOwner().getTown());
		System.out.println(getOwner().getfCountry().toUpperCase());
		System.out.println("**************************************");
		System.out.println("Balance:  " + getBalance());
		System.out.println("**************************************");
	}
	
	
	
	/* (non-Javadoc)
	 * @see AbstractAccount#withdrawal(double)
	 */
	public boolean withdrawal(double amount)
	{
		boolean withdrawalSuccessful = false;
		if(((getBalance() - amount) < 0) && (!fDebitAllowed))
		{
			withdrawalSuccessful = false;
		}
		else if((getBalance() - amount) > -fDebitAmount)
		{
			setBalance(getBalance() - amount);
			withdrawalSuccessful = true;
		}
		return withdrawalSuccessful;
	}
	
	
	/**
	 * Applies this person and their account for a credit card. returns a new credit card if they are
	 * accepted, or null if they were not chosen to recieve a new card.
	 * 
	 * @param the_person
	 * @param accountNumber
	 * @return	a new credit card, or null if no credit card allowed.
	 */
	public CreditCard applyForCreditCard(final Person the_person, int accountNumber)
	{
		CreditCard newCard = null;
		if(!(getBalance() < 0))
		{
			if(getBalance() <= 2500)
			{
				newCard = new CreditCard(the_person);
			}
			else
			{
				newCard = new CreditCard(the_person, 5000);
			}
		}

		return newCard;
	}
	
	/**
	 * Increased the account balance by the amount.
	 * @param amount
	 */
	public void increaseBalance(double amount)
	{
		setBalance(getBalance() + amount);
	}
	
	/**
	 * Decreased the account balance by the amount.
	 * @param amount
	 */
	public void decreaseBalance(double amount)
	{
		setBalance(getBalance() - amount);
	}

	/**
	 * returns the amount negative that the account is allowed to go.
	 * @return
	 */
	public double getDebitAmount()
	{
		return fDebitAmount;
	}
	
	/**
	 * Returns the account owners name.
	 * @return
	 */
	public String getOwnerName() {
		return getOwner().getName();
	}
	
	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	public boolean equals(Object o)
	{
		boolean areEqual = false;
		if(o instanceof CheckingAccount && getAccountNumber() == ((CheckingAccount)o).getAccountNumber())
			areEqual = true;
		return areEqual;
				
	}
}
